<?php

namespace App\Repositories;

use App\Enums\AccountLogEnum;
use App\Enums\GiftEnum;
use App\Exceptions\BasicException;
use App\Models\MainDB\AccountLog;
use App\Models\MainDB\Gift as Gift;
use App\Models\MainDB\GiftPrice;
use App\Models\MainDB\GiftWall\GiftHallGift;
use App\Models\MainDB\GiftWall\GiftHallRewardRecord;
use App\Models\MainDB\GiftWall\GiftHallRewardRecordLog;
use App\Models\MainDB\LiveCoinLog;
use App\Models\MainDB\RoomCharm;
use App\Models\MainDB\User;
use App\Models\MainDB\UserData;
use App\Models\MainDB\UserRoom;
use App\Models\SociatyDB\Hall;
use App\Models\SociatyDB\Sociaty;
use App\Repositories\Activity\ValentinesNetworkRepository;
use App\Services\Tools\PushService;
use App\Services\Tools\RedisService;
use Carbon\Carbon;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class GiftRepository
{
    //生成redis排行数据
    public function afterGiveGift($data)
    {
        //更新排行榜数据
        $this->updateRankData($data);

        //更新礼物墙数据
        $this->addUserGiftWall($data);

        //更新周星榜数据
        $this->addWeekStarData($data);

        //同步流水记录到公会库
        $this->sync_income($data);

        //更新礼物墙排行榜
        $lastNumber = app('model_user_gift_wall')->where('user_id', $data['gift_user'])->where('gift_id',
            $data['gift_id'])->value('number');
        app('repo_gift_wall')->updateUserGiftWallRank($data['gift_user'], $data['gift_id'],
            $lastNumber ? $lastNumber : 0);

        //送礼增加亲密值
        app('repo_connection')->intimacyIncreaseByGift($data['user_id'], [$data['gift_user']], $data['total_price'],
            $data['room_id'], $data['gift_id']);

        //房间争霸送礼增加积分
        //app('repo_roompk')->giveGiftIncreaseIntegral($data['user_id'], $data['room_id'], $data['gift_id'], $data['total_price'], $data['number']);

        //春节排行榜
        //app('repo_spring_festival_rank')->sfrankUpdate($data['user_id'], [$data['gift_user']], $data['number'], $data['total_price'], $data['gift_id']);

        //2021 520活动 更新排行榜
        $valenLogic = new ValentinesNetworkRepository();
        if ($valenLogic->active()) {
            $valenLogic->addUserRankScore($data['user_id'], $data['gift_user'], $data['gift_id'], $data['number'],
                $data['give_gift_record_id'] ?? 0);
        }
    }

    public function updateRankData($data)
    {
        $user_id     = $data['user_id'];
        $gift_user   = $data['gift_user'];
        $room_id     = $data['room_id'];
        $total_price = $data['total_price'];
        $give_date   = date('Y-m-d', $data['add_time']);

        $insert_data = [
            'user_id'   => $user_id,
            'give_date' => $give_date,
            'room_id'   => $room_id,
            'total'     => $total_price,
        ];

        $where       = ['user_id' => $user_id, 'give_date' => $give_date, 'room_id' => $room_id];
        $result_rich = app('model_give_gift_rich')->where($where)->first();
        if ($result_rich) {
            app('model_give_gift_rich')->where('id', $result_rich->id)->increment('total', $total_price);
        } else {
            app('model_give_gift_rich')->insert($insert_data);
        }

        $where['user_id'] = $gift_user;
        $result_charm     = app('model_give_gift_charm')->where($where)->first();
        if ($result_charm) {
            app('model_give_gift_charm')->where('id', $result_charm->id)->increment('total', $total_price);
        } else {
            $insert_data['user_id'] = $gift_user;
            app('model_give_gift_charm')->insert($insert_data);
        }
    }

    public function addUserGiftWall($data)
    {
        $result = RedisService::addUserGiftWall($data['gift_user'], $data['gift_id']);
        if ($result) {
            app('model_user_gift_wall')->insert([
                'user_id'  => $data['gift_user'],
                'gift_id'  => $data['gift_id'],
                'get_time' => Carbon::now()->timestamp,
                'number'   => $data['number'],
            ]);
        } else {
            app('model_user_gift_wall')->where([
                'user_id' => $data['gift_user'],
                'gift_id' => $data['gift_id'],
            ])->increment('number', $data['number']);
        }
    }

    public function getCurrentWeekStarGift()
    {
        $weeks = date('oW');
        $key   = 'weekstar:gift:' . $weeks;
        if (app('redis')->exists($key)) {
            return app('redis')->hgetall($key);
        } else {
            $result = app('model_week_star')->where(['weeks' => $weeks, 'deleted' => 0, 'is_status' => 0])->first();
            if (!$result) {
                return [];
            } else {
                $result = $result->toArray();
            }
            app('redis')->hmset($key, $result);
            app('redis')->expire($key, todayLeftTime());

            return $result;
        }
    }

    //周星数据，个人统计每个礼物数量，房间统计金币价格
    public function addWeekStarData($data)
    {
        $week_star_gift = $this->getCurrentWeekStarGift();
        if (!$week_star_gift) {
            return false;
        }
        $total = $data['total_price'];
        if ($total <= 0) {
            return false;
        }
        $gift_ids = explode(',', $week_star_gift['gift_ids']);
        if (!in_array($data['gift_id'], $gift_ids)) {
            return false;
        }

        $room_id = $data['room_id'];
        $weeks   = date('oW');
        if ($room_id > 0) {//房间统计总价值
            $key_room = 'weekstar:room:' . $weeks;
//            app('redis')->zincrby($key_room, $total, $room_id);
            zSetRedisScore($key_room, $total, $room_id);
        }
        //个人根据礼物分类统计数量
        $key_rich  = 'weekstar:rich:'. $weeks. ':'.$data['gift_id'];
        $key_charm = 'weekstar:charm:'. $weeks. ':'.$data['gift_id'];

        zSetRedisScore($key_rich, $data['number'], $data['user_id']);
        zSetRedisScore($key_charm, $data['number'], $data['gift_user']);
//        app('redis')->zincrby($key_rich, $data['number'], $data['user_id']);
//        app('redis')->zincrby($key_charm, $data['number'], $data['gift_user']);
    }

    /*同步流水记录到公会库*/
    public function sync_income($data)
    {
        $hall_have = app('model_sc_income')->select('id')->where(['give_id' => $data['id']])->first();
        if ($hall_have) {
            return false;
        }
        /*厅流水*/
        $hall_res = app('model_sc_hall')->select('id', 'sociaty_id', 'add_time')->where([
            'room_id' => $data['room_id'],
            'status'  => 3,
        ])->first();
        if (!$hall_res || $data['add_time'] < $hall_res->add_time) {
            return false;
        }
        $type = 2;
        /*成员流水*/
        $sociaty_user_res = app('model_sc_sociaty_user')->where([
            'user_id'    => $data['gift_user'],
            'sociaty_id' => $hall_res->sociaty_id,
        ])->first();
        if ($sociaty_user_res && $data['add_time'] > $sociaty_user_res->add_time) {
            $type = 1;
        }
        /*流水记录*/ //2025-04-17
        app('model_sc_income')->insert([
            'amount'   => $data['total_price'],
            'user_id'  => $data['gift_user'],
            'uid'      => $data['user_id'],
            'sc_id'    => $hall_res['sociaty_id'],
            'hall_id'  => $hall_res['id'],
            'add_time' => $data['add_time'],
            'ctime'    => time(),
            'room_id'  => $data['room_id'],
            'give_id'  => $data['id'],
            'type'     => $type,
            'types'     => $data['type'],
        ]);
    }


    /*同步流水金额公会会长钱包*/
    public function sociaty_master_gift(array $data)
    {
        //房间ID查询工会
        $sociaty = Hall::where(['room_id' => $data['room_id']])->first();
        if (!$sociaty) {
            return false;
        }
        $sociatyMaster = Sociaty::where(['id' => $sociaty->sociaty_id, 'status' => 3])->first();
        if (!$sociatyMaster) {
            return false;
        }

        $userData = UserData::whereIn('user_id', [$data['user_id'], $data['gift_user']])->pluck('nickname', 'user_id')->toArray();
        $gift     = Gift::where(['id' => $data['gift_id']])->first();
        $roomId   = UserRoom::where(['id' => $data['room_id']])->value("room_id");
        $exists   = AccountLog::where(['change_type' => 234, 'user_id' => $sociatyMaster->user_id, 'source_id' => $data['id'], 'room_id' => $data['room_id']])->first();
        if ($exists) {
            dump("记录已存在");
            return false;
        }
        Db::transaction(function () use ($data, $sociatyMaster, $userData, $gift, $roomId) {
            $addMoney = bcmul($data['total_price'], 0.15, 2);
            User::where(['user_id' => $sociatyMaster->user_id])->increment('earnings', $addMoney);
            $ext = ['money_field' => 'earnings'];
            app('model_account_log')->addLog($sociatyMaster->user_id, $data['total_price'], "房间ID:{$roomId} {$userData[$data['user_id']]}送给{$userData[$data['gift_user']]} {$gift->name}"
                , 234, $data['id'], $data['room_id'], $ext);
        });

    }


    public function updateRank($data)
    {
        $redis = app('redis');

        $user_id     = $data['user_id'];
        $gift_user   = $data['gift_user'];
        $room_id     = $data['room_id'];
        $total_price = round($data['total_price']);
        $add_time    = $data['add_time'];

        $rank_rich_day  = 'rank:rich:day:' . date('Ymd', $add_time);          //财富榜日榜
        $rank_charm_day = 'rank:charm:day:' . date('Ymd', $add_time);         //魅力榜日榜
        $redis->zincrby($rank_rich_day, $total_price, $user_id);
        $redis->zincrby($rank_charm_day, $total_price, $gift_user);

        $rank_rich_week  = 'rank:rich:week:' . date('oW', $add_time); //财富榜周榜
        $rank_charm_week = 'rank:charm:week:' . date('oW', $add_time);//魅力榜周榜
        $redis->zincrby($rank_rich_week, $total_price, $user_id);
        $redis->zincrby($rank_charm_week, $total_price, $gift_user);

        $rank_rich_month  = 'rank:rich:month:' . date('Ym', $add_time); //财富榜月榜
        $rank_charm_month = 'rank:charm:month:' . date('Ym', $add_time);//魅力榜月榜
        $redis->zincrby($rank_rich_month, $total_price, $user_id);
        $redis->zincrby($rank_charm_month, $total_price, $gift_user);

        //小时榜 总榜
        $rank_rich_hour  = 'rank:rich:hour:' . date('YmdH', $add_time); //财富榜小时榜
        $rank_charm_hour  = 'rank:charm:hour:' . date('YmdH', $add_time); //魅力榜小时榜
        $redis->zincrby($rank_rich_hour, $total_price, $user_id);
        $redis->zincrby($rank_charm_hour, $total_price, $gift_user);
        $redis->expire($rank_rich_hour, 10800);
        $redis->expire($rank_charm_hour, 10800);

        if ($room_id > 0) {
            $suffix = ':' . $room_id;
            $redis->zincrby($rank_rich_day . $suffix, $total_price, $user_id);
            $redis->zincrby($rank_charm_day . $suffix, $total_price, $gift_user);

            $redis->zincrby($rank_rich_week . $suffix, $total_price, $user_id);
            $redis->zincrby($rank_charm_week . $suffix, $total_price, $gift_user);

            $redis->zincrby($rank_rich_month . $suffix, $total_price, $user_id);
            $redis->zincrby($rank_charm_month . $suffix, $total_price, $gift_user);

            $redis->zincrby($rank_rich_hour . $suffix, $total_price, $user_id);
            $redis->zincrby($rank_charm_hour . $suffix, $total_price, $gift_user);
            $redis->expire($rank_rich_hour . $suffix, 10800);
            $redis->expire($rank_charm_hour . $suffix, 10800);

            //房间排行-日榜
            $rank_room_key = 'rank:room:day:'.date('Ymd', $add_time);
            $redis->zincrby($rank_room_key, $total_price, $room_id);
            $redis->expire($rank_room_key, 259200);
        }
    }

    public function addUserGetGiftWall($data)
    {
        //0送礼物1黄金2白银3青铜守护4聊天送礼物5送背包礼物6竞拍成功
        if (!in_array($data['type'], [0, 4, 5])) {
            return true;
        }
        $isShowInWall = app('model_gift')->where('id', $data['gift_id'])->value('is_show_in_wall');
        if (!$isShowInWall) {
            return true;
        }

        try {
            $model = app('model_user_gift_wall')
                ->newQuery()
                ->where('user_id', $data['gift_user'])
                ->where('gift_id', $data['gift_id'])
                ->where('type', 1)
                ->first();
            if (!$model) {
                $giftPrice   = intval($data['total_price'] / $data['number']);
                $giftWallExp = $this->getGiftExp($giftPrice);
                RedisService::addUserGiftWallExp($data['gift_user'], $giftWallExp);
                app('model_user_gift_wall_exp_log')->insert([
                    'type'        => 0,
                    'give_id'     => $data['id'],
                    'gift_id'     => $data['gift_id'],
                    'user_id'     => $data['gift_user'],
                    'exp'         => $giftWallExp,
                    'create_time' => time(),
                    'update_time' => time(),
                ]);

                app('model_user_gift_wall')->insert([
                    'user_id'  => $data['gift_user'],
                    'gift_id'  => $data['gift_id'],
                    'get_time' => Carbon::now()->timestamp,
                    'number'   => $data['number'],
                    'type'     => 1,
                ]);
            } else {
                $model->number += $data['number'];
                $model->save();
                // app('model_user_gift_wall')->where([
                //     'user_id' => $data['gift_user'],
                //     'gift_id' => $data['gift_id'],
                //     'type' => 1,
                // ])->increment('number', $data['number']);
            }

            // 所有展馆信息
            $halls = GiftHallRepository::getInstance()->normal();

            // 用户推送过的展馆
            $userCollectedRecord = GiftHallCollectPushLogRepository::getInstance()->userHalls((int)$data['gift_user']);

            //更新用户的展馆
            $hallIds  = $halls->pluck('id')->toArray();
            $giftHall = GiftHallGift::query()->where('gift_id', $data['gift_id'])->whereIn('hall_id', $hallIds)->get();

            if ($giftHall->isNotEmpty()) {
                $giftHall    = $giftHall->toArray();  //该礼物所在的展馆
                $hallIds     = array_column($giftHall, 'hall_id');
                $giftListIds = GiftHallRepository::getInstance()->getWallGift(); //所有礼物墙礼物

                $userGiftList = GiftHallRepository::getInstance()->getUserAllGiftMap($data['gift_user']); //获取的礼物['gift_id' => 'number']
                $userGiftIds  = array_keys($userGiftList);

                $hallToGift = GiftHallRepository::getInstance()->getHallGift($hallIds, $giftListIds);  //展馆对应的礼物
                $recordList = GiftHallRewardRecord::query()->where('user_id', $data['gift_user'])->whereIn('hall_id', $hallIds)->get();

                $insertData = $insertLog = [];
                foreach ($hallToGift as $hall => $gl) {
                    $record = $recordList->where('hall_id', $hall)->first();

                    //添加次数
                    $diff   = array_diff($gl, $userGiftIds);
                    $number = 0;
                    if (empty($diff)) {
                        foreach ($gl as $k => $g) {
                            if ($k == 0) {
                                $number = $userGiftList[$g];
                            } else {
                                $number = min($number, $userGiftList[$g]);
                            }
                        }
                    }

                    if ($record && $record->status == 2) {  //如果已经是高级的
                        if ($number > $record->number) {
                            GiftHallRewardRecord::query()->where('id', $record->id)->update(['number' => $number]);
                        }
                        continue;
                    }

                    $status = 0;
                    //$diff = array_diff($gl,$userGiftIds);
                    if (empty($diff)) {
                        $status = 2;
                        foreach ($gl as $g) {
                            if ($userGiftList[$g] < 10) {
                                $status = 1;
                                break;
                            }
                        }
                    }
                    if (!$record && $status > 0) {
                        $insertData[] = ['user_id' => $data['gift_user'], 'hall_id' => $hall, 'status' => $status, 'number' => $number];
                        $insertLog[]  = ['user_id' => $data['gift_user'], 'hall_id' => $hall, 'type' => $status, 'gift_ids' => json_encode($gl)];
                        continue;
                    }
                    $updateHall = [];
                    if ($record && $record->number < $number) {
                        $updateHall['number'] = $number;
                    }
                    if ($record && $record->status < $status) {
                        $updateHall['status'] = $status;
                        $insertLog[]          = ['user_id' => $data['gift_user'], 'hall_id' => $hall, 'type' => $status, 'gift_ids' => json_encode($gl)];
                    }
                    if (!empty($updateHall)) {
                        GiftHallRewardRecord::query()->where('id', $record->id)->update($updateHall);
                    }

                    if ($status > 0) {
                        // 是否推送过
                        $isPushed = $userCollectedRecord->where("hall_id", $hall)->where("type", $status)->isEmpty();
                        if ($isPushed) { // 推送
                            $roomId = $data['room_id'];
                            $userId = $data['gift_user'];

                            $key = "gift:hall:collected:push:{$userId}:{$status}";
                            if (!app('redis')->set($key, 1, 'ex', 60, 'nx')) {
                                return false;
                            }

                            $room = UserRoom::query()->where("id", $roomId)->select(["id", "room_id", "room_name"])->first();
                            if (!$room) {
                                return false;
                            }
                            $user        = UserData::query()->where("user_id", $userId)->select(["user_id", "user_code", "nickname", "head_picture"])->first();
                            $collectHall = $halls->where("id", $hall)->first();
                            if ($collectHall->is_push) {
                                $pushService = new PushService($userId, $roomId);
                                if ($status == 1) { // 普通
                                    $pushService->hallCollectedSpecial($user, $collectHall);
                                }
                                $pushService->hallCollectedBanner($user, $collectHall, $status);
                                GiftHallCollectPushLogRepository::getInstance()->push($userId, $hall, $status, $gl);
                            }
                        }
                    }
                }
                if (!empty($insertData)) {
                    GiftHallRewardRecord::query()->insert($insertData);
                }
                if (!empty($insertLog)) {
                    GiftHallRewardRecordLog::query()->insert($insertLog);
                }

            }

        } catch (\Exception $e) {
            throw new BasicException(-1, "礼物墙更新异常" . $e->getMessage());
        }
    }

    public function addUserGiveGiftWall($data)
    {
        //0送礼物1黄金2白银3青铜守护4聊天送礼物5送背包礼物6竞拍成功
        if (!in_array($data['type'], [0, 4, 5])) {
            return true;
        }
        $isShowInWall = app('model_gift')->where('id', $data['gift_id'])->value('is_show_in_wall');
        if (!$isShowInWall) {
            return true;
        }
        try {
            $model = app('model_user_gift_wall')
                ->newQuery()
                ->where('user_id', $data['user_id'])
                ->where('gift_id', $data['gift_id'])
                ->where('type', 2)
                ->first();
            if (!$model) {
                app('model_user_gift_wall')->insert([
                    'user_id'  => $data['user_id'],
                    'gift_id'  => $data['gift_id'],
                    'get_time' => Carbon::now()->timestamp,
                    'number'   => $data['number'],
                    'type'     => 2,
                ]);
            } else {
                $model->number += $data['number'];
                $model->save();
                // app('model_user_gift_wall')->where([
                //     'user_id' => $data['user_id'],
                //     'gift_id' => $data['gift_id'],
                //     'type' => 2,
                // ])->increment('number', $data['number']);
            }
        } catch (\Exception $e) {
            throw new BasicException(-1, '礼物墙更新异常' . $e->getMessage());
        }
    }

    private function getGiftExp($giftPrice)
    {
        if ($giftPrice <= 0) {
            return 0;
        }
        switch ($giftPrice) {
            case $giftPrice >= 300000:
                $exp = 15;
                break;
            case $giftPrice >= 100000 && $giftPrice <= 299999:
                $exp = 10;
                break;
            case $giftPrice >= 10000 && $giftPrice <= 99999:
                $exp = 4;
                break;
            case $giftPrice >= 1 && $giftPrice <= 9999:
                $exp = 1;
                break;
            default:
                $exp = 0;
                break;
        }
        return $exp;
    }

    // 礼物记录
    public function batchGiftRecord(
        int $roomId,
        $sendUserInfo,
        array $acceptUserList,
        Collection $giftInfoList,
        int $type,
        int $changeType = 0,
        int $giveCount = 1,
        int $input,
        int $draw_id
    )
    {
        //校验礼物数量是否正常 $draw_id 备用
        if ($giftInfoList->sum('count') < count($acceptUserList) * $giveCount) {
            throw new BasicException(-1, '奖品数量异常');
        }
        $sociatyInfo = app('model_sc_hall')->getSociatyInfo($roomId);
        $room = UserRoom::query()->where('id',$roomId)->first();
        $roomCode = $room->room_id;
        $union_user_id = $room['union_type'] == 1 ? 'hall_user_id' : 'user_id'; //日返类型 1返给厅主 2会长
        $union_title = $room['union_type'] == 1 ? '厅主' : '会长';
        $cardiacList      = [];
        $userEarningsList = [];
        $sociatyEarningsList = [];
        $roomCharmData    = $giveGiftRecordList = $getUsers = $accountLog = $giftPriceLog = [];
        // 获取收益百分比
        $earningsConfigArr   = app("repo_config")->queryConfig('EARNINGS'); // 礼物收益百分比
        $earningsConfigValue = $earningsConfigArr['value'] ? $earningsConfigArr['value'] / 100 : 0.65;
        $UNION_INCOME = app("repo_config")->queryConfig('UNION_INCOME')['value'] ?? 0.2; // 公会收益

        //生成随机接收礼物用户列表
        $randomAcceptUserList = $randomAcceptUserNum = [];
        $acceptUserList = array_column($acceptUserList, NULL, 'user_id');
        foreach ($giftInfoList as $giftInfo) {
            for ($j = 0; $j < $giftInfo['count']; $j++) {
                $acceptUser = $acceptUserList[array_rand($acceptUserList)];
                $give_gift_key = $acceptUser['user_id'].'_'.$giftInfo['id'];
                if (isset($randomAcceptUserList[$give_gift_key])) {
                    $randomAcceptUserList[$give_gift_key]['number'] += 1;
                } else {
                    $acceptUser['gift_id'] = $giftInfo['id'];
                    $acceptUser['number'] = 1;
                    $randomAcceptUserList[$give_gift_key] = $acceptUser;
                }
                $randomAcceptUserNum[$acceptUser['user_id']] ++;
                //达到最大数量$giveCount 剔除
                if ($randomAcceptUserNum[$acceptUser['user_id']] >= $giveCount) {
                    unset($acceptUserList[$acceptUser['user_id']]);
                }

            }
        }
        $getMoneyUserId = array_merge(array_column($randomAcceptUserList, 'user_id'), [$sendUserInfo['id'], $sociatyInfo->$union_user_id]);
        $getMoneyUserList = app('model_user')->getMoneyUserList($getMoneyUserId);
        $giftInfoListArray = array_column($giftInfoList->toArray(), NULL, 'id');

        foreach ($randomAcceptUserList as $acceptUser) {
            $acceptUserId = $acceptUser['user_id'];
            $pit          = $acceptUser['pit'];
            $nickname     = $acceptUser['nickname'] ?? '';
            $giftId       = $acceptUser['gift_id'];
            $giftNumber   = $acceptUser['number'];

            $giftInfoAry = $giftInfoListArray[$giftId];
            //延续改版前逻辑、避免报错
            $giftInfo = app('model_gift')->fill($giftInfoAry);

            //累计用户收益和心动值
            if (!empty($userEarningsList[$acceptUserId])) {
                $userEarningsList[$acceptUserId] += abs($giftInfo->price * $giftNumber) * $earningsConfigValue;
            } else {
                $userEarningsList[$acceptUserId] = abs($giftInfo->price * $giftNumber) * $earningsConfigValue;
            }
            if (!empty($cardiacList[$pit])) {
                $cardiacList[$pit]['cardiac'] += $giftInfo->cardiac * $giftNumber;
            } else {
                $cardiacList[$pit]['pit']        = $pit;
                $cardiacList[$pit]['pit_number'] = $pit;
                $cardiacList[$pit]['cardiac']    = $giftInfo->cardiac * $giftNumber;
            }

            $data = [
                'number'      => $giftNumber,
                'user_id'     => $sendUserInfo['id'],
                'gift_id'     => $giftInfo->id,
                'room_id'     => $roomId,
                'add_time'    => time(),
                'total_price' => abs($giftInfo->price * $giftNumber),
                'type'        => $type,
            ];

            $acceptUserNickname = RedisService::getUserBaseInfo($acceptUserId, 'nickname', true);
            $data['gift_user']  = $acceptUserId;
            $data['pit_number'] = $pit;
            $giveGiftData []    = $data;
            $giveGiftId         = GiveGiftRepository::getInstance()->giveGift($data);
            $giveGiftIdArr[]    = $giveGiftId;

            app('redis')->del('user:gift:wall:' . $acceptUserId);
            $accountLog[]   = [
                'user_id'     => $sendUserInfo['id'],
                'user_money'  => $input,
                'change_time' => time(),
                'change_desc' => '送给 ' . $acceptUserNickname . ' ' . $giftInfo->name,
                'change_type' => $changeType,
                'room_id'     => $roomId,
                'popularity'  => 0,
                'source_id'   => $giveGiftId,
                'after_money' => $getMoneyUserList[$sendUserInfo['id']]['money'],
            ];
            $getMoneyUserList[$acceptUserId]['earnings'] += abs($giftInfo->price * $giftNumber)*$earningsConfigValue;
            $accountLog[]   = [
                'user_id'     => $acceptUserId,
                'user_money'  => abs($giftInfo->price * $giftNumber)*$earningsConfigValue,
                'change_time' => time(),
                'change_desc' => '收到 ' . $sendUserInfo['nickname'] . ' ' . $giftInfo->name,
                'change_type' => 6,
                'room_id'     => $roomId,
                'popularity'  => 0,
                'source_id'   => $giveGiftId,
                'after_money' => $getMoneyUserList[$acceptUserId]['earnings'],
            ];
            $union_fee = round(abs($giftInfo->price * $giftNumber) * $UNION_INCOME, 2);
            //工会
            if($sociatyInfo){
                //日返更改为 给 厅主
                $getMoneyUserList[$sociatyInfo->$union_user_id]['earnings'] += $union_fee;
                $accountLog[] = [
                    'user_id' => $sociatyInfo->$union_user_id,
                    'user_money' => $union_fee,
                    'change_time' => time(),
                    'change_desc' => "魔法卡牌：日返 房间ID:{$roomCode} {$sendUserInfo['nickname']}送给{$acceptUserNickname} {$giftInfo['name']} 返给{$union_title}： {$sociatyInfo->$union_user_id}",
                    'change_type' => 234,
                    'room_id' => $roomId,
                    'popularity' => 0,
                    'source_id' => $giveGiftId,
                    'after_money' => $getMoneyUserList[$sociatyInfo->$union_user_id]['earnings'],
                ];
            }
            if (!empty($sociatyEarningsList[$sociatyInfo->$union_user_id])) {
                $sociatyEarningsList[$sociatyInfo->$union_user_id] += $union_fee;
            } else {
                $sociatyEarningsList[$sociatyInfo->$union_user_id] = $union_fee;
            }


            $giftPriceLog[] = [
                'user_id'   => $sendUserInfo['id'],
                'gift_user' => $acceptUserId,
                'number'    => abs($giftInfo->price * $giftNumber),
                'room_id'   => $roomId,
                'add_time'  => time(),
            ];

            if (isset($giveGiftRecordList[$acceptUserId][$giftInfo->id])) {
                $giveGiftRecordList[$acceptUserId][$giftInfo->id]['number'] += $giftNumber;
            } else {
                $giveGiftRecordList[$acceptUserId][$giftInfo->id] = [
                    'give_gift_id'  => $giveGiftId,
                    'user_id'       => $acceptUserId,
                    'user_id_from'  => $sendUserInfo['id'],
                    'nickname_from' => $sendUserInfo['nickname'],
                    'nickname_to'   => $nickname,
                    'gift_id'       => $giftInfo->id,
                    'pit_number'    => $pit,
                    'gift_name'     => $giftInfo->name ?? '',
                    'price'         => $giftInfo->price ?? 0,
                    'picture'       => $giftInfo->picture ?? '',
                    'special'       => $giftInfo->special ?? '',
                    'gift_info'     => $giftInfoAry,
                    'number'        => $giftNumber,
                ];
            }

            $roomCharmData[]         = [
                'number_count' => abs($giftInfo->price * $giftNumber) > 5000 ? 1 : 0,
                'room_id'      => $roomId,
                'pit_number'   => $pit,
                'gift_id'      => $giftInfo->id,
                'number'       => $giftInfo->cardiac * $giftNumber,
                'user_id'      => $sendUserInfo->id,
                'put_user'     => $acceptUserId,
                'add_time'     => time(),
            ];
            $getUsers[$acceptUserId] = $acceptUserNickname;
        }

        if ($roomId > 0) {
            $batchRes = app('model_room_cardiac')->batchUpdateRoomCardiac($roomId, $cardiacList);
            //当送给非麦位人时 批量更新魅力为空
//            if (!$batchRes) {
//                throw new BasicException(-1, '批量更新魅力失败');
//            }
        }

        // 批量写入
        $accountLogRes = AccountLog::query()->insert($accountLog);
        if (!$accountLogRes) {
            throw new BasicException(-1, '批量计入用户日志失败');
        }

        // 批量写入
        $giftPriceRes = GiftPrice::query()->insert($giftPriceLog);
        if (!$giftPriceRes) {
            throw new BasicException('批量插入礼物记录失败');
        }

        // 批量记录房间魅力 // number不是礼物数量， number = 礼物心动值 * 赠送数量
        RoomCharm::query()->insert($roomCharmData);

        $charm = array_sum(array_column($roomCharmData, 'number'));

        RedisService::setRoomCharm($roomId, $charm); // 加房间心动值总数.

//        // 单人直播送礼
        if (!empty($liveCoinList)) {
            LiveRepository::getInstance()->batchUpdateLiveCoin($liveCoinList);
        }
        if (!empty($liveCoinLogList)) {
            LiveCoinLog::query()->insert($liveCoinLogList);
        }

        //记录用户带来的魅力值
        foreach ($cardiacList as $cardiacPit => $cardiacValue) {
            RedisService::setRoomCardiac($roomId, $cardiacPit, $cardiacValue['cardiac']);
        }

        // 增加收礼物人的收益
        $resUser = app('repo_user')->batchUpdateUserEarnings($userEarningsList);
        if (!$resUser) {
            throw new BasicException(-1, '批量更新用户收益失败');
        }
        // 厅主到钱包
        if($sociatyInfo){
            $resUser = app('repo_user')->batchUpdateUserEarnings($sociatyEarningsList);
            if (!$resUser) {
                throw new BasicException(-1, '批量更新用户收益失败');
            }
        }
        return ['give_gift_ids' => $giveGiftIdArr, 'give_gift_record_list' => $giveGiftRecordList];
    }


    // 礼物记录 旧版
    public function batchGiftRecordLast(
        int $roomId,
        $sendUserInfo,
        array $acceptUserList,
        Collection $giftInfoList,
        int $type,
        int $changeType = 0,
        int $giveCount = 1,
        int $input,
        int $draw_id
    )
    {
        //校验礼物数量是否正常
        if ($giftInfoList->sum('count') < count($acceptUserList) * $giveCount) {
            throw new BasicException(-1, '奖品数量异常');
        }
        //生成随机接收礼物用户列表
        $randomAcceptUserList = [];
        foreach ($acceptUserList as $acceptUser) {
            for ($i = 0; $i < $giveCount; $i++) {
                $randomAcceptUserList[] = $acceptUser;
            }
        }
        shuffle($randomAcceptUserList);
        $individualLive = LiveRepository::getInstance()->getNormalLive($roomId);
        $sociatyInfo=Hall::query()
            ->leftJoin('sc_sociaty as sc', 'sc.id', '=', 'sc_hall.sociaty_id')
            ->where(['room_id'=>$roomId])
            ->where(['sc_hall.status'=>3,'sc.status'=>3])->select(['sc.user_id','sc_hall.room_id', 'sc_hall.user_id as hall_user_id'])
            ->first();
        $roomCode = UserRoom::query()->where('id',$roomId)->value('room_id');
        $cardiacList      = [];
        $userEarningsList = [];
        $sociatyEarningsList = [];
        $roomCharmData    = $giveGiftRecordList = $getUsers = $accountLog = $giftPriceLog = [];
        // 获取收益百分比
        $earningsConfigArr   = app("repo_config")->queryConfig('EARNINGS'); // 礼物收益百分比
        $earningsConfigValue = $earningsConfigArr['value'] ? $earningsConfigArr['value'] / 100 : 0.65;
        $UNION_INCOME = app("repo_config")->queryConfig('UNION_INCOME')['value'] ?? 0.2; // 公会收益
        $pitCardiacList      = [];
        $liveCoinList        = [];

        $getMoneyUserId = array_merge(array_column($randomAcceptUserList, 'user_id'), [$sendUserInfo['id'], $sociatyInfo->hall_user_id]);
        $getMoneyUserList = app('model_user')->getMoneyUserList($getMoneyUserId);

        foreach ($giftInfoList as $giftInfo) {
            if (count($randomAcceptUserList) <= 0) {
                break;
            }
            for ($j = 0; $j < $giftInfo->count; $j++) {
                $acceptUserId = current($randomAcceptUserList)['user_id'];
                $pit          = current($randomAcceptUserList)['pit'];
                $nickname     = current($randomAcceptUserList)['nickname'] ?? '';


                //累计用户收益和心动值
                if (!empty($userEarningsList[$acceptUserId])) {
                    $userEarningsList[$acceptUserId] += abs($giftInfo->price) * $earningsConfigValue;
                } else {
                    $userEarningsList[$acceptUserId] = abs($giftInfo->price) * $earningsConfigValue;
                }
                if (!empty($cardiacList[$pit])) {
                    $cardiacList[$pit]['cardiac'] += $giftInfo->cardiac;
                } else {
                    $cardiacList[$pit]['pit']        = $pit;
                    $cardiacList[$pit]['pit_number'] = $pit;
                    $cardiacList[$pit]['cardiac']    = $giftInfo->cardiac;
                }

                $data = [
                    'number'      => 1,
                    'user_id'     => $sendUserInfo['id'],
                    'gift_id'     => $giftInfo->id,
                    'room_id'     => $roomId,
                    'add_time'    => time(),
                    'total_price' => abs($giftInfo->price),
                    'type'        => $type,
                ];

                $acceptUserNickname = RedisService::getUserBaseInfo($acceptUserId, 'nickname', true);
                $data['gift_user']  = $acceptUserId;
                $data['pit_number'] = $pit;
                $giveGiftData []    = $data;
                $giveGiftId         = GiveGiftRepository::getInstance()->giveGift($data);
                $giveGiftIdArr[]    = $giveGiftId;

                if (isset($individualLive->id) && $individualLive->user_id == $acceptUserId) {
                    $liveCoinLogList[] = [
                        "live_id"    => $individualLive->id,
                        'type'       => LiveRepository::LIVE_GIFT_LOG_TYPE,
                        "coin"       => abs($giftInfo->price),
                        "foreign_id" => $giveGiftId,
                    ];
                    if (isset($liveCoinList[$individualLive->id])) {
                        $liveCoinList[$individualLive->id] += $giftInfo->price;
                    } else {
                        $liveCoinList[$individualLive->id] = $giftInfo->price;
                    }
                }

                app('redis')->del('user:gift:wall:' . $acceptUserId);
                $accountLog[]   = [
                    'user_id'     => $sendUserInfo['id'],
                    'user_money'  => $input,
                    'change_time' => time(),
                    'change_desc' => '送给 ' . $acceptUserNickname . ' ' . $giftInfo->name,
                    'change_type' => $changeType,
                    'room_id'     => $roomId,
                    'popularity'  => 0,
                    'source_id'   => $giveGiftId,
                    'after_money' => $getMoneyUserList[$sendUserInfo['id']]['money'],
                ];
                $getMoneyUserList[$acceptUserId]['earnings'] += abs($giftInfo->price)*$earningsConfigValue;
                $accountLog[]   = [
                    'user_id'     => $acceptUserId,
                    'user_money'  => abs($giftInfo->price)*$earningsConfigValue,
                    'change_time' => time(),
                    'change_desc' => '收到 ' . $sendUserInfo['nickname'] . ' ' . $giftInfo->name,
                    'change_type' => 6,
                    'room_id'     => $roomId,
                    'popularity'  => 0,
                    'source_id'   => $giveGiftId,
                    'after_money' => $getMoneyUserList[$acceptUserId]['earnings'],
                ];
                $union_fee = round(abs($giftInfo->price) * $UNION_INCOME, 2);
                //工会
                if($sociatyInfo){
                    //日返更改为 给 厅主
                    $getMoneyUserList[$sociatyInfo->hall_user_id]['earnings'] += $union_fee;
                    $accountLog[] = [
                        'user_id' => $sociatyInfo->hall_user_id,
                        'user_money' => $union_fee,
                        'change_time' => time(),
                        'change_desc' => "魔法卡牌：日返 房间ID:{$roomCode} {$sendUserInfo['nickname']}送给{$acceptUserNickname} {$giftInfo['name']} 返给厅主： {$sociatyInfo->hall_user_id}",
                        'change_type' => 234,
                        'room_id' => $roomId,
                        'popularity' => 0,
                        'source_id' => $giveGiftId,
                        'after_money' => $getMoneyUserList[$sociatyInfo->hall_user_id]['earnings'],
                    ];
                }
                if (!empty($sociatyEarningsList[$sociatyInfo->hall_user_id])) {
                    $sociatyEarningsList[$sociatyInfo->hall_user_id] += $union_fee;
                } else {
                    $sociatyEarningsList[$sociatyInfo->hall_user_id] = $union_fee;
                }


                $giftPriceLog[] = [
                    'user_id'   => $sendUserInfo['id'],
                    'gift_user' => $acceptUserId,
                    'number'    => abs($giftInfo->price),
                    'room_id'   => $roomId,
                    'add_time'  => time(),
                ];

                if (isset($giveGiftRecordList[$acceptUserId][$giftInfo->id])) {
                    $giveGiftRecordList[$acceptUserId][$giftInfo->id]['number']++;
                } else {
                    $giveGiftRecordList[$acceptUserId][$giftInfo->id] = [
                        'give_gift_id'  => $giveGiftId,
                        'user_id'       => $acceptUserId,
                        'user_id_from'  => $sendUserInfo['id'],
                        'nickname_from' => $sendUserInfo['nickname'],
                        'nickname_to'   => $nickname,
                        'gift_id'       => $giftInfo->id,
                        'pit_number'    => $pit,
                        'gift_name'     => $giftInfo->name ?? '',
                        'price'         => $giftInfo->price ?? 0,
                        'picture'       => $giftInfo->picture ?? '',
                        'special'       => $giftInfo->special ?? '',
                        'gift_info'     => $giftInfo->toArray(),
                        'number'        => 1,
                    ];
                }

                $roomCharmData[]         = [
                    'number_count' => abs($giftInfo->price) > 5000 ? 1 : 0,
                    'room_id'      => $roomId,
                    'pit_number'   => $pit,
                    'gift_id'      => $giftInfo->id,
                    'number'       => $giftInfo->cardiac,
                    'user_id'      => $sendUserInfo->id,
                    'put_user'     => $acceptUserId,
                    'add_time'     => time(),
                ];
                $getUsers[$acceptUserId] = $acceptUserNickname;

                $shiftUser = array_shift($randomAcceptUserList);

                if (empty($shiftUser)) {
                    break;
                }
            }
        }

        if ($roomId > 0) {
            $batchRes = app('model_room_cardiac')->batchUpdateRoomCardiac($roomId, $cardiacList);
            //当送给非麦位人时 批量更新魅力为空
//            if (!$batchRes) {
//                throw new BasicException(-1, '批量更新魅力失败');
//            }
        }

        // 批量写入
        $accountLogRes = AccountLog::query()->insert($accountLog);
        if (!$accountLogRes) {
            throw new BasicException(-1, '批量计入用户日志失败');
        }

        // 批量写入
        $giftPriceRes = GiftPrice::query()->insert($giftPriceLog);
        if (!$giftPriceRes) {
            throw new BasicException('批量插入礼物记录失败');
        }

        // 批量记录房间魅力 // number不是礼物数量， number = 礼物心动值 * 赠送数量
        RoomCharm::query()->insert($roomCharmData);

        $charm = array_sum(array_column($roomCharmData, 'number'));

        RedisService::setRoomCharm($roomId, $charm); // 加房间心动值总数.

//        // 单人直播送礼
        if (!empty($liveCoinList)) {
            LiveRepository::getInstance()->batchUpdateLiveCoin($liveCoinList);
        }
        if (!empty($liveCoinLogList)) {
            LiveCoinLog::query()->insert($liveCoinLogList);
        }

        //记录用户带来的魅力值
        foreach ($cardiacList as $cardiacPit => $cardiacValue) {
            RedisService::setRoomCardiac($roomId, $cardiacPit, $cardiacValue['cardiac']);
        }

        // 增加收礼物人的收益
        $resUser = app('repo_user')->batchUpdateUserEarnings($userEarningsList);
        if (!$resUser) {
            throw new BasicException(-1, '批量更新用户收益失败');
        }
        // 厅主到钱包
        if($sociatyInfo){
            $resUser = app('repo_user')->batchUpdateUserEarnings($sociatyEarningsList);
            if (!$resUser) {
                throw new BasicException(-1, '批量更新用户收益失败');
            }
        }
        return ['give_gift_ids' => $giveGiftIdArr, 'give_gift_record_list' => $giveGiftRecordList];
    }

    // 批量用户收入
    public function batchUpdateUserEarnings(array $earningList)
    {
        if (empty($earningList)) {
            return true;
        }
        $userIds   = array_keys($earningList);
        $userIdStr = implode(',', $userIds);

        $table = app('model_user')->getTable();
        $sql   = "update {$table} set ";
        // 增加数量
        $sql .= "`earnings` = case ";
        foreach ($earningList as $userId => $earning) {
            $sql .= "when user_id = {$userId}  then `earnings` + {$earning} ";
        }
        $sql .= "else `earnings` end ";
        // 条件
        $sql .= " where  user_id in ($userIdStr)";
        return DB::update($sql);
    }

    public function giftsByIds($ids)
    {
        $query = Gift::query();
        $query->whereIn('id', $ids);
        $query->select(['id', 'title as name', 'img as picture', 'price']);
        $models = $query->get();
        return $models;
    }

    public function find(int $id)
    {
        $query = Gift::query();
        return $query->find($id);
    }

    public function giftsByIdsWithField($ids, $fields)
    {
        $query = Gift::query();
        $query->whereIn('id', $ids);
        $query->select($fields);
        $models = $query->get();
        return $models;
    }

    public function one(array $filters, bool $fail = false)
    {
        $query = Gift::query();
        $query->where($filters);
        $model = $fail ? $query->firstOrFail() : $query->first();
        return $model;
    }
}
